#ifndef     __SENSOR_H
#define     __SENSOR_H

#include "../../utils/object.h"
#include "../../utils/nocopyable.h"
#include "../../rtos/mutex.h"
#include "../../utils/base.h"

namespace driver {

class Sensor : private utils::NoCopyable {

public:
 
    Sensor();

    inline bool is_stir_top() { 
        return utils::is_clr_bit<2>(read());
    }

    inline bool is_stir_bottom() {
        return utils::is_clr_bit<3>(read());
    }

    inline bool is_water_left() {
        return utils::is_set_bit<4>(read());
    }

    inline bool is_water_right() {
        return utils::is_set_bit<5>(read());
    }

    inline bool is_ice_left() {
        return utils::is_set_bit<6>(read());
    }

    inline bool is_ice_right() {
        return utils::is_set_bit<7>(read());
    }

    bool is_leak();
    bool is_bucket_high();
    bool is_bucket_low();
    bool is_outlet_high();
    bool is_outlet_low();

    uint16_t flow_count();
    uint16_t flow();

    void flow_reset();

    uint16_t status() { 
        using namespace utils;

        uint8_t sw = read();
        uint16_t tmp = (is_clr_bit<2>(sw)) |
            (is_clr_bit<3>(sw) << 1) |
            (is_set_bit<4>(sw) << 2) |
            (is_set_bit<5>(sw) << 3) |
            (is_set_bit<6>(sw) << 4) |
            (is_set_bit<7>(sw) << 5);
        
        tmp |= is_leak() << 6;
        tmp |= is_bucket_high() << 7;
        tmp |= is_bucket_low() << 8;
        tmp |= is_outlet_high() << 9;
        tmp |= is_outlet_low() << 10;
        return tmp;
    }

private:
    uint8_t read();

    rtos::Mutex m_mutex;
};

inline utils::Object<Sensor> sensor;

}

#endif
